﻿using System;
using LS.DataTable;
using UnityEngine;
using UnityGameFramework.Runtime;

namespace LS.Entity
{
    public static class EntityExtension
    {
        // 关于 EntityId 的约定：
        // 0 为无效
        // 正值用于和服务器通信的实体（如玩家角色、NPC、怪等，服务器只产生正值）
        // 负值用于本地生成的临时实体（如特效、FakeObject等）
        public readonly static SerialIdGenerator SerialIdGenerator = new SerialIdGenerator(int.MinValue, -1,-1);

        public static EntityBase GetGameEntity(this EntityComponent entityComponent, int entityId)
        {
            UnityGameFramework.Runtime.Entity entity = entityComponent.GetEntity(entityId);
            if (entity == null)
            {
                return null;
            }

            return (EntityBase)entity.Logic;
        }

        public static void HideEntity(this EntityComponent entityComponent, EntityBase entity)
        {
            entityComponent.HideEntity(entity.Entity);
        }

        public static void HideEntity(this EntityComponent entityComponent, int entityTypeId)
        {
            IEntityData dataRow = LSEntry.DataTable.GetDataRow(LSEntry.LSBase.m_DataTableDefaultSetting.EntityDataType, entityTypeId) as IEntityData;
            if (dataRow != null)
            {
                string assetName = dataRow.AssetName;
                var entities = entityComponent.GetEntities(assetName);
                foreach (var entity in entities)
                {
                    entityComponent.HideEntity(entity);
                }
            }
        }
        
        public static void AttachEntity(this EntityComponent entityComponent, EntityBase entity, int ownerId, string parentTransformPath = null, object userData = null)
        {
            entityComponent.AttachEntity(entity.Entity, ownerId, parentTransformPath, userData);
        }

        public static int? ShowEntity(this EntityComponent entityComponent, int entityTypeId, Type logicType = null, object userData = null)
        {
            IEntityData dataRow = LSEntry.DataTable.GetDataRow(LSEntry.LSBase.m_DataTableDefaultSetting.EntityDataType, entityTypeId) as IEntityData;
            if (dataRow == null)
            {
                Log.Warning("Can not load Entity form '{0}' from data table.", entityTypeId.ToString());
                return null;
            }
            
            EntityParams  parm = null;
            if (userData is not null && userData is EntityParams)
            {
                parm = userData as EntityParams;
            }
            else
            {
                parm = EntityParams.Create<EntityParams>(userData);
                parm.EntityTypeId = entityTypeId;
                parm.Position = Vector3.zero;
                parm.Rotation = Quaternion.identity;
            }
            
            if (logicType == null)
            {
                logicType = typeof(EmptyEntityLogic);
            }
            
            int serialId = GenerateSerialId(null);
            string assetName = LSPath.FormatEntityUnityAsset(dataRow.AssetName);
            entityComponent.ShowEntity(serialId, logicType, assetName, dataRow.EntityGroupName, LS.Constant.AssetPriority.EntityAsset, parm);
            return serialId;
        }
        
        public static int GenerateSerialId(this EntityComponent entityComponent)
        {
            return SerialIdGenerator.Generate();
        }
    }
}
